using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using System.Text;
using Jonathan.Classes;

namespace Jonathan.Controls
{
   /// <summary>
   /// Daily devotional control.
   /// </summary>
   public partial class CtrlDailyDevotional : UserControl
   {
      private string m_Title = "";
      private string m_Text = "";
      private readonly FrmMain m_FormMain;
      private fHtmlToolTip m_MoToolTip;
      private bool m_TtShown;

      /// <summary>
      /// Initializes a new daily devitional control.
      /// </summary>
      /// <param name="main">Main form.</param>
      public CtrlDailyDevotional (FrmMain main)
      {
         InitializeComponent ();
         this.m_FormMain = main;
         this.m_TtShown = false;

         // Set Custom Paint Styles...
         this.SetStyle (ControlStyles.AllPaintingInWmPaint, true);
         this.SetStyle (ControlStyles.DoubleBuffer, true);
         this.SetStyle (ControlStyles.ResizeRedraw, true);
         this.SetStyle (ControlStyles.Selectable, true);
         this.SetStyle (ControlStyles.SupportsTransparentBackColor, true);
         this.SetStyle (ControlStyles.UserPaint, true);
      }

      protected override void OnPaintBackground (PaintEventArgs e)
      {
         base.OnPaintBackground (e);

         GraphicsPath p = Common.RoundRect (new RectangleF (this.ClientRectangle.X + 10,
                                                          this.ClientRectangle.Y + 10,
                                                          this.ClientRectangle.Width - 20,
                                                          this.ClientRectangle.Height - 20), 8, 8, 8, 8);

         LinearGradientBrush lgb = new LinearGradientBrush (new RectangleF (this.ClientRectangle.X + 10,
                                                           this.ClientRectangle.Y + 10,
                                                           this.ClientRectangle.Width - 20,
                                                           this.ClientRectangle.Height - 20), Color.White, Color.LightGray,
                                                           LinearGradientMode.ForwardDiagonal);

         e.Graphics.FillPath (lgb, p);

         e.Graphics.DrawPath (new Pen (Color.LightGray), p);
      }

      protected override void OnPaint (PaintEventArgs e)
      {
         base.OnPaint (e);

         e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
         Assembly assem = this.GetType ().Assembly;
         System.Resources.ResourceManager mngr = new System.Resources.ResourceManager ("Jonathan.InternalImages", assem);
         Image dailyDev = (Image)mngr.GetObject ("DailyDevotional");

         if (dailyDev != null)
         {
            if (dailyDev.Width > this.ClientRectangle.Width - 40)
            {
               int w = this.ClientRectangle.Width - 40;
               if (w > 0)
               {
                  e.Graphics.DrawImage (dailyDev, new Rectangle (25, 15, w, dailyDev.Height));
               }
            }
            else
            {
               e.Graphics.DrawImage (dailyDev, new Point (25, 15));
            }

            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            StringFormat fmt = new StringFormat
                                  {
                                     Trimming = StringTrimming.EllipsisWord,
                                     FormatFlags = StringFormatFlags.LineLimit
                                  };
            int h = TextRenderer.MeasureText ("Tg", this.Font).Height;

            // Draw Title...
            e.Graphics.DrawString (this.m_Title, new Font (this.Font.FontFamily.Name, this.Font.Size, FontStyle.Bold),
                                   Brushes.Black, new RectangleF (25, 20 + dailyDev.Height,
                                                                  this.ClientRectangle.Width - 40,
                                                                  this.Bottom - (h * 7) - 25), fmt);

            SizeF size = e.Graphics.MeasureString (this.m_Title,
                                                   new Font (this.Font.FontFamily.Name, this.Font.Size, FontStyle.Bold),
                                                   this.ClientRectangle.Width - 40, fmt);
            this._TxtMain.Top = Convert.ToInt32 (20 + dailyDev.Height + size.Height + 10);
            this._TxtMain.Height = this.Height - this._TxtMain.Top - 150;
            this._TxtMain.Width = this.Width - (this._TxtMain.Left * 2);
            this._PnlRef.Top = this._TxtMain.Bottom + 5;
            this._PnlRef.Width = this._TxtMain.Width;
         }
      }

      /// <summary>
      /// Sets the data to display.
      /// </summary>
      /// <param name="title">Title to display.</param>
      /// <param name="text">Text to display</param>
      /// <param name="refs">References.</param>
      /// <param name="notes">Notes</param>
      public void SetData (string title, string text, string refs, string notes)
      {
         this.m_Text = text;
         this.m_Title = title;
         string[] txt = this.m_Text.Split (new [] { "<p>" }, StringSplitOptions.RemoveEmptyEntries);
         StringBuilder sb = new StringBuilder ();
         foreach (string t in txt)
         {
            if (sb.Length > 0)
            {
               sb.Append (Environment.NewLine);
               sb.Append (Environment.NewLine);
            }
            sb.Append (t);
         }
         this._TxtMain.Text = sb.ToString ();
         this._TxtMain.ScrollBars = ScrollBars.Vertical;

         string[] refSplit = refs.Split ('|');
         foreach (string reference in refSplit)
         {
            if (!string.IsNullOrEmpty (reference))
            {
               LinkLabel ll = new LinkLabel
                  {
                     AutoSize = true,
                     Text = reference,
                     LinkColor = Color.DarkRed,
                     Margin = new Padding (1, 0, 0, 0)
                  };
               ll.Click += LlClick;
               ll.MouseEnter += LlMouseEnter;
               ll.MouseLeave += LlMouseLeave;
               this._PnlRef.Controls.Add (ll);
            }
         }
      }

      #region - Close ToolTip -

      /// <summary>
      /// Close the Tool Tip if Open...
      /// </summary>
      private void CloseTt ()
      {
         if (this.m_TtShown)
         {
            if (this.m_MoToolTip != null)
            {
               this.m_MoToolTip.Close ();
               this.m_MoToolTip.Dispose ();
               this.m_MoToolTip = null;
               this.m_TtShown = false;
            }
         }
      }

      #endregion

      void LlMouseLeave (object sender, EventArgs e)
      {
         if (this.m_TtShown)
         {
            this.CloseTt ();
         }
      }

      void LlMouseEnter (object sender, EventArgs e)
      {
         if (this.m_FormMain.ProgramData.MouseOverToolTips)
         {
            this.m_TtShown = true;
            LinkLabel ll = sender as LinkLabel;
            if (ll != null)
            {
               StringBuilder sb = GetPassageText (ll.Text);

               m_MoToolTip = new fHtmlToolTip (this.m_FormMain, this._PnlRef.PointToScreen (new Point (ll.Left, ll.Bottom)), sb.ToString (), ll.Text, false);
            }
         }
      }

      void LlClick (object sender, EventArgs e)
      {
         LinkLabel ll = sender as LinkLabel;
         if (ll != null)
         {
            StringBuilder sb = GetPassageText (ll.Text);

            fHtmlToolTip tt = new fHtmlToolTip (this.m_FormMain, this._PnlRef.PointToScreen (new Point (ll.Left, ll.Bottom)), sb.ToString (), ll.Text, true);
            tt.ShowTT ();
         }
      }

      /// <summary>
      /// Gets the text for the passage in question...
      /// </summary>
      /// <param name="pass">Passages to get text for.</param>
      /// <returns>String Builder with text.</returns>
      private StringBuilder GetPassageText (string pass)
      {
         List<CPassage> passages = Parser.Parse (pass);
         StringBuilder text;
         using (SQLiteConnection dbConn = new SQLiteConnection (Common.ConnString (this.m_FormMain.DefaultBibleFile)))
         {
            dbConn.Open ();
            text = Common.GetToolTipText (passages, this.m_FormMain.ProgramData.DefaultBible, dbConn.CreateCommand ());
         }
         return text;
      }
   }
}
